﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlTypes;
using System.Data;
using Jalal.Library.DataStructure;
using Jalal.Library.Utility;
using Jalal.Library.Data;
using BCGC.DAL;

namespace BCGC.BLL.BusinessObject
{
    public class Contact
    {
        private int contactId;
        public int ContactId
        {
            get { return contactId; }
            private set { contactId = value; }
        }

        private string clientName;
        public string ClientName
        {
            get { return clientName; }
            set { clientName = value; }
        }

        private string clientOrganization;
        public string ClientOrganization
        {
            get { return clientOrganization; }
            set { clientOrganization = value; }
        }

        private string clientPhone;
        public string ClientPhone
        {
            get { return clientPhone; }
            set { clientPhone = value; }
        }

        private string clientEmail;
        public string ClientEmail
        {
            get { return clientEmail; }
            set { clientEmail = value; }
        }

        private string clientWebsite;
        public string ClientWebsite
        {
            get { return clientWebsite; }
            set { clientWebsite = value; }
        }

        private string contactSubject;
        public string ContactSubject
        {
            get { return contactSubject; }
            set { contactSubject = value; }
        }

        private string contactDescription;
        public string ContactDescription
        {
            get { return contactDescription; }
            set { contactDescription = value; }
        }

        private DateTime contactDateTime;
        public DateTime ContactDateTime
        {
            get { return contactDateTime; }
            set { contactDateTime = value; }
        }

        private bool isRead;
        public bool IsRead
        {
            get { return isRead; }
            set { isRead = value; }
        }

        public Contact()
        {
            this.contactId = 0;
            this.clientName = string.Empty;
            this.clientOrganization = string.Empty;
            this.clientEmail = string.Empty;
            this.clientPhone = string.Empty;
            this.clientWebsite = string.Empty;
            this.contactDescription = string.Empty;
            this.contactSubject = string.Empty;
            this.contactDateTime = SqlDateTime.MinValue.Value;
            this.isRead = false;
        }

        public Contact(DataRow dataRow)
        {
            if (dataRow != null)
            {
                if (dataRow.Table.Columns.Contains("ContactId"))
                    this.contactId = (int)CommonUtility.FilterNull(dataRow["ContactId"], typeof(int));
                if (dataRow.Table.Columns.Contains("ClientName"))
                    this.clientName = (string)CommonUtility.FilterNull(dataRow["ClientName"], typeof(string));
                if (dataRow.Table.Columns.Contains("ClientOrganization"))
                    this.clientOrganization = (string)CommonUtility.FilterNull(dataRow["ClientOrganization"], typeof(string));
                if (dataRow.Table.Columns.Contains("ClientEmail"))
                    this.clientEmail = (string)CommonUtility.FilterNull(dataRow["ClientEmail"], typeof(string));
                if (dataRow.Table.Columns.Contains("ClientPhone"))
                    this.clientPhone = (string)CommonUtility.FilterNull(dataRow["ClientPhone"], typeof(string));
                if (dataRow.Table.Columns.Contains("ClientWebsite"))
                    this.clientWebsite = (string)CommonUtility.FilterNull(dataRow["ClientWebsite"], typeof(string));
                if (dataRow.Table.Columns.Contains("ContactDescription"))
                    this.contactDescription = (string)CommonUtility.FilterNull(dataRow["ContactDescription"], typeof(string));
                if (dataRow.Table.Columns.Contains("ContactSubject"))
                    this.contactSubject = (string)CommonUtility.FilterNull(dataRow["ContactSubject"], typeof(string));
                if (dataRow.Table.Columns.Contains("ContactDateTime"))
                    this.contactDateTime = (DateTime)CommonUtility.FilterNull(dataRow["ContactDateTime"], typeof(DateTime));
                if (dataRow.Table.Columns.Contains("IsRead"))
                    this.isRead = (bool)CommonUtility.FilterNull(dataRow["IsRead"], typeof(bool));
            }
            else
            {
                this.contactId = 0;
                this.clientName = string.Empty;
                this.clientOrganization = string.Empty;
                this.clientEmail = string.Empty;
                this.clientPhone = string.Empty;
                this.clientWebsite = string.Empty;
                this.contactDescription = string.Empty;
                this.contactSubject = string.Empty;
                this.contactDateTime = SqlDateTime.MinValue.Value;
                this.isRead = false;
            }
        }

        private static ReadWriteCustomCollection<Contact> LoadFromDataTable(DataTable data)
        {
            ReadWriteCustomCollection<Contact> result = new ReadWriteCustomCollection<Contact>();

            if (data != null && data.Rows.Count > 0)
            {
                foreach (DataRow row in data.Rows)
                {
                    result.Add(new Contact(row));
                }
            }
            return result;
        }

        public static bool Create(string clientName, string clientOrganization,
            string clientEmail, string clientPhone, string clientWebsite, string contactSubject,
            string contactDescription, DateTime contactDateTime, bool isRead)
        {
            DataFactory.GetDataMiner().BeginTransaction(true);
            int id = ContactData.CreateNewContact(clientName, clientOrganization, clientEmail, clientPhone,
                clientWebsite, contactSubject, contactDescription, contactDateTime, isRead);
            DataFactory.GetDataMiner().CommitTransaction();

            return (id > 0);
        }

        public bool Update()
        {
            DataFactory.GetDataMiner().BeginTransaction(true);

            int count = ContactData.UpdateContactData(this.contactId, this.clientName, 
                this.clientOrganization,this.clientEmail, this.clientPhone, this.clientWebsite,
                this.contactSubject, this.contactDescription, this.contactDateTime, this.isRead);

            DataFactory.GetDataMiner().CommitTransaction();

            return (count == 1);
        }

        public static ReadWriteCustomCollection<Contact> GetAllContact(int currentPageIndex, string sortOrder, int pageSize,
            string searchName, string searchOrganization, DateTime? searchContactDateFrom, DateTime? searchContactDateTo, 
            bool? isRead, out int totalData)
        {
            DataFactory.GetDataMiner().BeginTransaction(true);

            totalData = 0;

            DataTable contactData = ContactData.GetAllContacts(currentPageIndex, sortOrder, pageSize, searchName,
                searchOrganization, searchContactDateFrom, searchContactDateTo, isRead, out totalData);
            ReadWriteCustomCollection<Contact> contacts = LoadFromDataTable(contactData);

            DataFactory.GetDataMiner().CommitTransaction();

            return contacts;
        }

        public static Contact Load(int contactId)
        {
            DataFactory.GetDataMiner().BeginTransaction(true);

            Contact contact = null;
            DataTable data = ContactData.GetContactById(contactId);
            if (data.Rows.Count > 0)
                contact = new Contact(data.Rows[0]);

            DataFactory.GetDataMiner().CommitTransaction();

            return contact;
        }

        public static void Delete(List<int> contactItemIds)
        {
            DataFactory.GetDataMiner().BeginTransaction(false);

            try
            {
                int deletedItemCount = ContactData.DeleteContacts(contactItemIds);
                if (deletedItemCount == contactItemIds.Count)
                    DataFactory.GetDataMiner().CommitTransaction();
                else
                    throw new Exception("Failed to delete all items");
            }
            catch (Exception ex)
            {
                DataFactory.GetDataMiner().RollBackTransaction();
                throw ex;
            }
        }

        public static void UpdateRead(List<int> contactItemIds)
        {
            DataFactory.GetDataMiner().BeginTransaction(false);

            try
            {
                int updatedItemCount = ContactData.UpdateReadItems(contactItemIds);
                if (updatedItemCount == contactItemIds.Count)
                    DataFactory.GetDataMiner().CommitTransaction();
                else
                    throw new Exception("Failed to update all items");
            }
            catch (Exception ex)
            {
                DataFactory.GetDataMiner().RollBackTransaction();
                throw ex;
            }
        }

        public static void UpdateUnread(List<int> contactItemIds)
        {
            DataFactory.GetDataMiner().BeginTransaction(false);

            try
            {
                int updatedItemCount = ContactData.UpdateUnreadItems(contactItemIds);
                if (updatedItemCount == contactItemIds.Count)
                    DataFactory.GetDataMiner().CommitTransaction();
                else
                    throw new Exception("Failed to update all items");
            }
            catch (Exception ex)
            {
                DataFactory.GetDataMiner().RollBackTransaction();
                throw ex;
            }
        }
    }
}
